/**
 * Copyright 2013 yangming.liu<liuyangming@gmail.com>.
 *
 * This copyrighted material is made available to anyone wishing to use, modify,
 * copy, or redistribute it subject to the terms and conditions of the GNU
 * Lesser General Public License, as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
 * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
 * for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this distribution; if not, see <http://www.gnu.org/licenses/>.
 */
package org.bytesoft.openjta.recovery;

import java.util.Iterator;

import org.bytesoft.openjta.archive.TerminatorArchive;
import org.bytesoft.openjta.archive.XAResourceArchive;

public class RegularRecoveredTransactionImpl extends RecoveredTransaction {
	private static final long serialVersionUID = 1L;

	protected void regulatePreparingTransaction(boolean failureExists) throws IllegalStateException {
		boolean existsNotPrepare = false;
		boolean existsPrepareFailure = false;
		boolean existsPrepareUnknown = false;

		Iterator<XAResourceArchive> xaResourceItr = this.xaResourceArchives.iterator();
		while (xaResourceItr.hasNext()) {
			XAResourceArchive archive = xaResourceItr.next();
			if (archive.isPrepareStarted()) {
				if (archive.isPrepareSuccess()) {
					// ignore
				} else if (archive.isPrepareFailure()) {
					existsPrepareFailure = true;
				} else {
					existsPrepareUnknown = true;
				}
			} else {
				existsNotPrepare = true;
			}
		}

		Iterator<TerminatorArchive> terminatorItr = this.terminatorArchives.iterator();
		while (terminatorItr.hasNext()) {
			TerminatorArchive archive = terminatorItr.next();
			if (archive.isPrepareStarted()) {
				if (archive.isPrepareSuccess()) {
					// ignore
				} else if (archive.isPrepareFailure()) {
					existsPrepareFailure = true;
				} else {
					existsPrepareUnknown = true;
				}
			} else {
				existsNotPrepare = true;
			}
		}

		if (existsNotPrepare || existsPrepareFailure || existsPrepareUnknown) {
			this.recoveryRollbackRequired = true;
		} else {
			this.recoveryRollbackRequired = false;

			transactionStatus.transferToPrepared();
			transactionLogger.completePreparePhase(this);
		}

	}

	protected void regulatePreparedTransaction() throws IllegalStateException {
		// do nothing
	}

	protected void regulateCommittingTransaction(boolean failureExists) throws IllegalStateException {

		this.recoveryRollbackRequired = false;

		boolean existsNotCommit = false;
		boolean existsCommitFailure = false;
		boolean existsCommitUnknown = false;

		Iterator<XAResourceArchive> xaResourceItr = this.xaResourceArchives.iterator();
		while (xaResourceItr.hasNext()) {
			XAResourceArchive archive = xaResourceItr.next();
			if (archive.isCommitStarted()) {
				if (archive.isCommitStarted()) {
					// ignore
				} else if (archive.isCommitFailure()) {
					existsCommitFailure = true;
				} else {
					existsCommitUnknown = true;
				}
			} else {
				existsNotCommit = true;
			}
		}

		Iterator<TerminatorArchive> terminatorItr = this.terminatorArchives.iterator();
		while (terminatorItr.hasNext()) {
			TerminatorArchive archive = terminatorItr.next();
			if (archive.isCommitStarted()) {
				if (archive.isCommitSuccess()) {
					// ignore
				} else if (archive.isCommitFailure()) {
					existsCommitFailure = true;
				} else {
					existsCommitUnknown = true;
				}
			} else {
				existsNotCommit = true;
			}
		}

		if (existsNotCommit || existsCommitFailure || existsCommitUnknown) {
			// ignore
		} else {
			transactionStatus.transferToCommitted();
			transactionLogger.completeCommitPhase(this);
		}
	}

	protected void regulateRollingbackTransaction(boolean failureExists) throws IllegalStateException {

		this.recoveryRollbackRequired = true;

		boolean existsNotRollback = false;
		boolean existsRollbackFailure = false;
		boolean existsRollbackUnknown = false;

		Iterator<XAResourceArchive> xaResourceItr = this.xaResourceArchives.iterator();
		while (xaResourceItr.hasNext()) {
			XAResourceArchive archive = xaResourceItr.next();
			if (archive.isRollbackStarted()) {
				if (archive.isRollbackSuccess()) {
					// ignore
				} else if (archive.isRollbackFailure()) {
					existsRollbackFailure = true;
				} else {
					existsRollbackUnknown = true;
				}
			} else {
				existsNotRollback = true;
			}
		}

		Iterator<TerminatorArchive> terminatorItr = this.terminatorArchives.iterator();
		while (terminatorItr.hasNext()) {
			TerminatorArchive archive = terminatorItr.next();
			if (archive.isRollbackStarted()) {
				if (archive.isRollbackSuccess()) {
					// ignore
				} else if (archive.isRollbackFailure()) {
					existsRollbackFailure = true;
				} else {
					existsRollbackUnknown = true;
				}
			} else {
				existsNotRollback = true;
			}
		}

		if (existsNotRollback || existsRollbackFailure || existsRollbackUnknown) {
			// ignore
		} else {
			transactionStatus.transferToRolledback();
			transactionLogger.completeRollbackPhase(this);
		}
	}

}
